package eam

import javafx.beans.property.*
import org.codehaus.groovy.ast.ASTNode
import org.codehaus.groovy.ast.ClassHelper
import org.codehaus.groovy.ast.ClassNode
import org.codehaus.groovy.ast.MethodNode
import org.codehaus.groovy.ast.builder.AstBuilder
import org.codehaus.groovy.control.CompilePhase
import org.codehaus.groovy.control.SourceUnit
import org.codehaus.groovy.transform.ASTTransformation
import org.codehaus.groovy.transform.GroovyASTTransformation
import org.objectweb.asm.Opcodes

/**
 * Created by Misty on 2015/6/5.
 */
@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
class EAMTransformation implements ASTTransformation {
    protected static final ClassNode objectPropertyClass = ClassHelper.make(ObjectProperty.class, true);
    protected static final ClassNode booleanPropertyClass = ClassHelper.make(BooleanProperty.class);
    protected static final ClassNode doublePropertyClass = ClassHelper.make(DoubleProperty.class);
    protected static final ClassNode floatPropertyClass = ClassHelper.make(FloatProperty.class);
    protected static final ClassNode intPropertyClass = ClassHelper.make(IntegerProperty.class);
    protected static final ClassNode longPropertyClass = ClassHelper.make(LongProperty.class);
    protected static final ClassNode stringPropertyClass = ClassHelper.make(StringProperty.class);
    protected static final ClassNode listPropertyClass = ClassHelper.make(ListProperty.class);
    protected static final ClassNode mapPropertyClass = ClassHelper.make(MapProperty.class);
    protected static final ClassNode setPropertyClass = ClassHelper.make(SetProperty.class);

    protected static final ClassNode simpleBooleanPropertyClass = ClassHelper.make(SimpleBooleanProperty.class);
    protected static final ClassNode simpleDoublePropertyClass = ClassHelper.make(SimpleDoubleProperty.class);
    protected static final ClassNode simpleFloatPropertyClass = ClassHelper.make(SimpleFloatProperty.class);
    protected static final ClassNode simpleIntPropertyClass = ClassHelper.make(SimpleIntegerProperty.class);
    protected static final ClassNode simpleLongPropertyClass = ClassHelper.make(SimpleLongProperty.class);
    protected static final ClassNode simpleStringPropertyClass = ClassHelper.make(SimpleStringProperty.class);
    protected static final ClassNode simpleListPropertyClass = ClassHelper.make(SimpleListProperty.class);
    protected static final ClassNode simpleMapPropertyClass = ClassHelper.make(SimpleMapProperty.class);
    protected static final ClassNode simpleSetPropertyClass = ClassHelper.make(SimpleSetProperty.class);
    protected static final ClassNode simpleObjectPropertyClass = ClassHelper.make(SimpleObjectProperty.class, true);
//    protected static final ClassNode numberClassNode = ClassHelper.make(Number.class);


    @Override
    void visit(ASTNode[] nodes, SourceUnit source) {
        try {
            nodes.findAll { node -> node instanceof ClassNode }.each { classNode ->
                def name = "setText"
                def a = new AstBuilder().buildFromSpec {
                    method(name, Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, void) {
                        parameters {
                            parameter value: String
                        }
                        exceptions {}
                        block {
                            expression {
                                methodCall {
                                    methodCall {
                                        variable 'this'
                                        constant 'textProperty'
                                        argumentList {}
                                    }
                                    constant 'setValue'
                                    argumentList {
                                        variable 'value'
                                    }
                                }
                            }
                        }
                    }
                }
                DebugUtil.dump(a[0] as MethodNode)
                ClassNode.cast(classNode).addMethod(a[0] as MethodNode)
            }
        } catch (Exception e) {
            println e
        }
    }
}
